package com.ssm.pojo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;


import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


public class SerializationExample {
  public static void main(String[] args) throws IOException, ParseException {
    ObjectMapper mapper = new ObjectMapper();
    Album album = new Album("Kind Of Blue");
    album.setLinks(new String[]{"link1", "link2"});
    List<String> songs = new ArrayList<String>();
    songs.add("So What");
    songs.add("Flamenco Sketches");
    songs.add("Freddie Freeloader");
    album.setSongs(songs);
    Artist artist = new Artist();
    artist.name = "Miles Davis";
    SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
    artist.birthDate = format.parse("26-05-1926");
    album.setArtist(artist);
    album.addMusician("Miles Davis", "Trumpet, Band leader");
    album.addMusician("Julian Adderley", "Alto Saxophone");
    album.addMusician("Paul Chambers", "double bass");


    //让Json可以缩进，可读性更好，一般用在测试和开发阶段。
    mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
    //让map的key按自然顺序排列
    mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
    //日期输出格式
    SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
    mapper.setDateFormat(outputFormat);
    //默认情况下java类属性名就是输出的json字段名，但是可以采用注解的方式修改。如果你不想让java类和json绑定
    // 或者无法修改java类，这里采用如下另外一种方式。你需要重写如下两个方法，这个取决属性是public或者getter是public
    mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
      /**
       * @param config Configuration in used: either SerializationConfig or DeserializationConfig, depending on whether method is called during serialization or deserialization
       * @param field Field used to access property
       * @param defaultName Default name that would be used for property in absence of custom strategy
       * @return
       */
              @Override
      public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        if (field.getFullName().equals("Artist#name"))
        {
          return "Artist-Name";
        }
        return super.nameForField(config, field, defaultName);
      }


      /**
       * @param config Configuration in used: either SerializationConfig or DeserializationConfig, depending on whether method is called during serialization or deserialization
       * @param method Method used to access property.
       * @param defaultName Default name that would be used for property in absence of custom strategy
       * @return
       */
              @Override
      public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        if (method.getAnnotated().getDeclaringClass().equals(Album.class) && defaultName.equals("title"))
        {
          return "Album-Title";
        }
        return super.nameForGetterMethod(config, method, defaultName);
      }
    });
    //如果属性没有值，那么Json是会处理的，int类型为0，String类型为null，数组为[]，设置这个特性可以忽略空值属性
    mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
    mapper.writeValue(System.out, album);
  }
}